package sessionMenegment;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Random;
import java.util.logging.Logger;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

import controller.Controller;
import dataBase.Business;
import dataBase.Client;

public class SessionMgr {	 
	static private SessionMgr inst = new SessionMgr();
	public HashMap<String, String> tempBizKey;
	HashMap<String, String> tempClientKey;
	static public SessionMgr getInst(){
		return inst;
	}
	private SessionMgr() {
		tempBizKey = new HashMap<String, String>();
		tempClientKey = new HashMap<String, String>();
	}
	public String getHash(String input){
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] messageDigest = md.digest(input.getBytes());
			BigInteger number = new BigInteger(1, messageDigest);
			return number.toString(16);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// if exception was thrown
		return null;
	}
	
	public void addCoockie(HttpServletResponse response,String userName,String pass,String type){
		Cookie cookie = null;
		Cookie passCoockie = null;
		if(type.equals("userNameBusiness")){
			cookie = new Cookie("SyncaUserNameBiz", userName);
			passCoockie = new Cookie("SyncaPassBiz", getHash(pass));
		}
		else if (type.equals("userNameClient")){
			cookie = new Cookie("SyncaUserNameClient", userName);
			passCoockie = new Cookie("SyncaPassClient", getHash(pass));
		}
		cookie.setMaxAge(30*24*60*60);
		passCoockie.setMaxAge(30*24*60*60);
		response.addCookie(cookie);
		response.addCookie(passCoockie);
	}
	
	public boolean checkUser(HttpServletRequest request,HttpSession session){
		try{
			String bizUser = (String)session.getAttribute("userNameBusiness");
			String clientUser = (String)session.getAttribute("userNameClient");
			System.out.println("start "+clientUser);
			if(bizUser!=null && !bizUser.equals("")){
				System.out.println("session biz: "+bizUser);
				String randomString = (String)session.getAttribute("SyncaString");			
				if(randomString!=null && tempBizKey.get(bizUser).equals(randomString))
					return true;
				else{
					session.setAttribute("userNameBusiness", null);
					session.setAttribute("SyncaString", null);
					return false;
				}
			}
			else if(clientUser!=null && !clientUser.equals("")){
				String randomString = (String)session.getAttribute("SyncaString");
				System.out.println("random: "+randomString);
				System.out.println("check: "+tempClientKey.get(clientUser));
				if(randomString!=null && tempClientKey.get(clientUser).equals(randomString))
					return true;
				else{
					session.setAttribute("userNameClient", null);
					session.setAttribute("SyncaString", null);
					return false;
				}
			}
			
			Cookie tmp = getCookie(request,"SyncaUserNameClient");
			Cookie tmp2 = getCookie(request,"SyncaUserNameBiz");
			Controller controller = Controller.getInstance();
			if(tmp!=null){
				Cookie pass = getCookie(request,"SyncaPassClient");
				Client client = controller.getClient(tmp.getValue());
				if(pass.getValue().equals(getHash(client.getPassword()))){
					session.setAttribute("userNameClient", tmp.getValue());
					registerUser(session, tmp.getValue(),"client");
					return true;
				}
			}
			else if(tmp2!=null){
				System.out.println("biz cookie");
				Cookie pass = getCookie(request,"SyncaPassBiz");
				Business biz = controller.getBiz(tmp2.getValue());
				if(pass.getValue().equals(getHash(biz.getPassword()))){
					session.setAttribute("userNameBusiness", tmp2.getValue());
					registerUser(session, tmp2.getValue(),"biz");
					return true;
				}
			}
		}
		catch(Exception ex){
			return false;
		}
		
		return false;
		
	}
	public boolean checkClient(HttpServletRequest request,HttpSession session){
		try{
			

			String clientUser = (String)session.getAttribute("userNameClient");
			System.out.println("start "+clientUser);
			if(clientUser!=null && !clientUser.equals("")){
				String randomString = (String)session.getAttribute("SyncaString");
				System.out.println("random: "+randomString);
				System.out.println("check: "+tempClientKey.get(clientUser));
				if(randomString!=null && tempClientKey.get(clientUser).equals(randomString))
					return true;
				else{
					session.setAttribute("userNameClient", null);
					session.setAttribute("SyncaString", null);
					return false;
				}
			}
			//checkGoogle(session);
			Cookie tmp = getCookie(request,"SyncaUserNameClient");
			Controller controller = Controller.getInstance();
			if(tmp!=null){
				Cookie pass = getCookie(request,"SyncaPassClient");
				Client client = controller.getClient(tmp.getValue());
				if(pass.getValue().equals(getHash(client.getPassword()))){
					session.setAttribute("userNameClient", tmp.getValue());
					registerUser(session, tmp.getValue(),"client");
					return true;
				}
			}
		}
		catch(Exception ex){
			return false;
		}
		
		return false;
		

	}
	private boolean checkGoogle(HttpSession session){
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		Logger log = Logger.getLogger("SessionMgr");
		log.warning("Gmail User1 "+user);
	
		if(user!=null){
			String userName = user.getNickname();
			Client client = Controller.getInstance().getClient(userName);
			log.warning("Client "+client);
			if(client!=null && client.getPassword().equals("")){
				session.setAttribute("userNameClient",userName);
				registerUser(session, userName, "client");
				log.warning("Gmail User "+userName);
				return true;
			}
		}
		return false;
	}
	private Cookie getCookie(HttpServletRequest request, String input) {
		Cookie cookies [] = request.getCookies ();
		if(cookies!=null){
			for(Cookie c : cookies){
				if(c.getName().equals(input))
					return c;
			}
		}
		return null;
	}
	public void resetCookie(HttpServletRequest request,HttpServletResponse response , String cookieName){
		Cookie cookies [] = request.getCookies ();
		if(cookies!=null){
			for(Cookie c : cookies){
				if(c.getName().equals(cookieName)){
					c.setMaxAge(0);
					response.addCookie(c);
					break;
				}
			}
		}
	}
	public String getRandomString(){
		Random r = new Random();
	    return Long.toString(Math.abs(r.nextLong()), 36);
	}
	
	public void registerUser(HttpSession session,String userName,String type){
		String randomString = getRandomString();
		session.setAttribute("SyncaString", randomString);
		if(type.equals("client"))
			tempClientKey.put(userName, randomString);
		else
			tempBizKey.put(userName, randomString);
	}
	public void unregisterUser(HttpSession session,String userName){
		session.setAttribute("SyncaString", null);
		tempClientKey.remove(userName);
		tempBizKey.remove(userName);
	}
	public String getRandomUser(String userName){
		return tempBizKey.get(userName);
		
	}
	public String logOutUser(HttpSession session,HttpServletResponse response, HttpServletRequest request,String userName){
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		String result = "home.jsp";
		if(user!=null && session.getAttribute("googleUser").equals("yes")){
			result = userService.createLoginURL(Controller.getInstance().getSyncaWebAddress()+"/home.jsp");
		}
		
		unregisterUser(session, userName);	
		resetCookie(request, response, "SyncaUserNameClient");
		resetCookie(request, response, "SyncaPassClient");
		resetCookie(request, response, "SyncaUserNameBiz");
		resetCookie(request, response, "SyncaPassBiz");
		
		return result;
	}
}
